package com.coincalf.framework.utils;

import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.*;

/**
 * TokenUtil
 *
 * @author wix
 * @version v1.0
 * @date 2018/05/28
 */
@Component
public class TokenUtil {

    private static Logger log = LoggerFactory.getLogger(TokenUtil.class);


    /**
     * 签名密钥，须先通过执行init方法初始化
     */
    private static String key = "2c454296-cb5b-5ba0-96e8-206d2304d7a4";
//    private static String key;

    @Value("${token.key}")
    private void setKey(String key) {
        TokenUtil.key = key;
    }

    /**
     * token默认过期时长
     */
    public static int TOKEN_EXP_TIME = 1000 * 60 * 60 * 24;

    /**
     * 使用双重md5+key方式生成token
     *
     * @param claims 有效载荷
     * @return token
     */
    public static String createToken(Map<String, Object> claims) {
        verifyKey(key);
        String body = JSONObject.toJSONString(claims);
        String body64 = Base64Utils.encodeToString(body);
        String token = MD5Utils.md5(MD5Utils.md5(body64) + key);
        return body64 + "." + token;
    }

    /**
     * 解析Token，同时也能验证Token，当验证失败返回null
     *
     * @param token
     * @return Map<String, Object>
     */
    public static Map<String, Object> parserToken(String token) {
        try {
            verifyKey(key);
            String[] split = token.split("\\.");
            String body64 = split[0];
            String sign = split[1];
            if (sign.equals(MD5Utils.md5(MD5Utils.md5(body64) + key))) {
                return JSONObject.parseObject(Base64Utils.decodeToString(body64));
            }
        } catch (Exception e) {
            log.info("token verify failed: {}", token);
        }
        return null;
    }

    /**
     * 解析Token，同时也能验证Token，当验证失败返回null
     *
     * @param token
     * @return Map<String, Object>
     */
    public static Map<String, Object> parserImToken(String token) {
        try {
            verifyKey(key);
            String[] split = token.split("\\.");
            String body64 = split[0];
            String sign = split[1];
            if (sign.equals(MD5Utils.md5(MD5Utils.md5(body64) + key))) {
                return JSONObject.parseObject(Base64Utils.decodeToString(body64));
            } else {
                Map<String, Object> map = new HashMap();
                map.put("user_id", "tokenError");
                return map;
            }
        } catch (Exception e) {
            log.info("token verify failed: {}", token);
            Map<String, Object> map = new HashMap();
            map.put("user_id", "tokenError");
            return map;
        }
    }

    private static void verifyKey(String key) {
        if (key == null || key.isEmpty()) {
            throw new IllegalStateException("token key is empty.");
        }
    }

    //生成签名，用于接口认真
    public static void t2() {
        Map<String, String[]> map = new HashMap<String, String[]>() {{
//            put("token", new String[]{"eyJ1c2VyX2lkIjo2MzgzMjE5NTI5NTk3NTgzMzYsImxvZ2luX3RpbWUiOjE1NzIzNTgyMDI5NTYsInNhbHQiOiJmOGIxNTMifQ==.ea1021e6b07c798fa7e56b9dffe058ab"});
//			put("id",new String[]{"581067341064830976"});
//			put("createStatus",new String[]{"2"});
//			put("payStatus",new String[]{"2"});
            //put("eosAccount",new String[]{"chenzhijun12"});
            //	put("account",new String[]{"sskkkkjjskkj"});
            //	put("eosAccount",new String[]{"r3r32qrawree"});
            //	put("remark",new String[]{"090913"});
//			   put("safetyCode",new String[]{"qwer1234"});
//			   put("privateKey",new String[]{"5JM7yBEppaZy6SXqfF3qv22WtbfuG2WGMVnttMKmSxifTrWMLN5"});
//			  put("chainId",new String[]{"1002"});
//				put("account",new String[]{"ssskkkkkkjjj"});
            //put("eosAccount",new String[]{"chenzhijun12"});
            put("loginName", new String[]{"18720992943"});
            put("pwd", new String[]{"123456"});
            put("verifyCode", new String[]{""});
            //	put("cpuAmount",new String[]{"0.001"});
            //	put("netAmount",new String[]{"0.001"});
            //put("transType",new String[]{"5"});
            //	put("fromAddr",new String[]{"qwer12345gee"});
            //	put("pageNo",new String[]{"1"});
            //put("pageSize",new String[]{"10"});
            //	put("ramAmount",new String[]{"0.001"});
            //put("fromAccount",new String[]{"qwer12345gee"});
            //	put("toAccount",new String[]{"chenzhijun12"});
            //put("payStatus",new String[]{"2"});
            //	put("weatherImport",new String[]{"2"});
            //put("id",new String[]{"582643255494049793"});
            //	put("createStatus",new String[]{"2"});
            //	put("fromAccount",new String[]{"qwer12345gee"});
            //put("payVoucher",new String[]{"1223"});
            //	put("payVoucher",new String[]{"1223"});
            //	put("payType",new String[]{"1"});
            //put("eosAccount",new String[]{"111451234qwe"});
            //	put("address",new String[]{"37PGPcevRoo6ak5xyqg4gGJBJmXFU6rYSf"});
//			put("telephone",new String[]{"18720992943"});
        }};
        // 自然排序
        TreeMap<String, String[]> treeMap = new TreeMap<>(Comparator.naturalOrder());
        treeMap.putAll(map);
        // 排除sign
        treeMap.remove("sign");
        // 遍历
        StringBuilder buffer = new StringBuilder();
        Set<Map.Entry<String, String[]>> entrySet = treeMap.entrySet();
        for (Map.Entry<String, String[]> entry : entrySet) {
            String[] value = entry.getValue();
            buffer.append(entry.getKey()).append("=");
            for (String s : value) {
                buffer.append(s).append(",");
            }
            if (value.length > 0) {
                buffer.deleteCharAt(buffer.length() - 1);
            }
            buffer.append("&");
//            throw new IllegalStateException("token is empty.");
        }
        if (!treeMap.isEmpty()) {
            buffer.deleteCharAt(buffer.length() - 1);
        }
        System.out.println(buffer.toString());
//        String md5 = MD5Utils.md5(MD5Utils.md5(buffer.toString()) + "111222333444");
//		String md5 = MD5Utils.md5(MD5Utils.md5(buffer.toString()) + "scan_dev");
        String md5 = MD5Utils.md5(MD5Utils.md5(buffer.toString()) + "ZavE4Ym4rEtOo4x6iS3DaBX6HETozsbv");
        System.out.println(md5);
    }


    public static void main(String[] args) {
        Map<String, Object> map = new HashMap<>();
        map.put("phoneCode", "86");
        map.put("username", "19925270454");
        String token = TokenUtil.createToken(map);
        System.out.println(token);
    }

    private static void t3() {
        Map<String, Object> map = JSONObject.parseObject("{\n"
                + " \"loginToken\" : \"eyJ1c2VyX2lkIjo2Mzg2OTQ0MzUzNTMyNjQxMjgsImxvZ2luX3RpbWUiOjE1NzI0MTQwMTA0MzcsInNhbHQiOiI1NDZkMDYifQ==.9eec4367622cc8ba3a8a8ce708964755\",\n"
                + " \"id\" : \"638694435353264128\",\n"
                + " \"ts\" : \"1572414009\",\n"
                + " \"sign\" : \"5c1db4dda2878445471e0aeff97cbd44\",\n"
                + " \"name\" : \"137****8428\",\n"
                + " \"portrait\" : \"(null)\"\n"
                + " }", Map.class);
        // 自然排序
        TreeMap<String, Object> treeMap = new TreeMap<>(Comparator.naturalOrder());
        treeMap.putAll(map);
        // 排除sign
        treeMap.remove("sign");
        // 遍历
        StringBuilder buffer = new StringBuilder();
        Set<Map.Entry<String, Object>> entrySet = treeMap.entrySet();
        for (Map.Entry<String, Object> entry : entrySet) {
            Object value = entry.getValue();
            buffer.append(entry.getKey()).append("=").append(value);
            buffer.append("&");
            //            throw new IllegalStateException("token is empty.");
        }
        if (!treeMap.isEmpty()) {
            buffer.deleteCharAt(buffer.length() - 1);
        }
        System.out.println(buffer.toString());
        //        String md5 = MD5Utils.md5(MD5Utils.md5(buffer.toString()) + "111222333444");
        // String s = "{\"user_id\":638694435353264128,\"login_time\":1572324960787,\"salt\":\"546d06\"}";

        String token = createToken(map);
        System.out.println("token=" + token);
        String md5 = MD5Utils.md5(MD5Utils.md5(buffer.toString()) + "ZavE4Ym4rEtOo4x6iS3DaBX6HETozsbv");
        System.out.println(md5);
    }
}
